#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/ocl.hpp>

using namespace std;
using namespace cv;
using namespace cv::ocl;

#define GPU 1

int main()
{
    double t = 0.0;

    // 视频捕获 这里我外接了一个摄像头，对应的设备为/dev/video1
    VideoCapture vcap(1);

    if (!vcap.isOpened()) {
        cout << "Can not open video device" << std::endl;
        return -1;
    }

    std::vector<cv::ocl::PlatformInfo> plats;
    cv::ocl::getPlatfomsInfo(plats);
    const cv::ocl::PlatformInfo *platform = &plats[0];
    cout << "Platform Name:" << platform->name().c_str() << endl;

    cv::ocl::Device dev;
    platform->getDevice(dev,0);
    cout << "Device name:" << dev.name().c_str() << endl;    

#if GPU
    cv::ocl::setUseOpenCL(true);
    cout << "Use the OpenCL Deivice?" << cv::ocl::useOpenCL() << endl;

    UMat frame, grayFrame, edges;
    for(;;){
        // 读取视频帧
        vcap.read(frame); 
        t = (double)cv::getTickCount();    
        cv::cvtColor(frame,grayFrame,cv::COLOR_BGR2GRAY);        
        // 进行边缘检测
        cv::Canny(grayFrame, edges, 50, 150); 
        t = ((double)cv::getTickCount() - t) / cv::getTickFrequency();
        std::cout << "GPU Time Cost:" << t << "s" << std::endl;
        
        putText(edges, "Platform : " + platform->name(), Point(5, 30), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2);
        putText(edges, "Device : " + dev.name(), Point(5, 60), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2);    
        putText(edges, "Time : " + std::to_string(t) + " s", Point(5, 90), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2);

        // 显示边缘图像
        cv::imshow("Edges", edges); 

        int key = waitKey(30);
        if (key == 27 || key == 'q' || key == 'Q')
            break;
    }
#else
    cv::ocl::setUseOpenCL(false);
    cout << "Use the OpenCL Deivice?" << cv::ocl::useOpenCL() << endl;
    Mat frame, grayFrame, edges;
    for(;;){
        // 读取视频帧
        vcap.read(frame); 
        t = (double)cv::getTickCount();
        cv::cvtColor(frame,grayFrame,cv::COLOR_RGB2GRAY);
        // 进行边缘检测
        cv::Canny(grayFrame, edges, 50, 150); 
        t = ((double)cv::getTickCount() - t) / cv::getTickFrequency();
        std::cout << "CPU Time Cost:" << t << "s" << std::endl;
        
        putText(edges, "Time : " + std::to_string(t) + " s", Point(5, 30), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2);

        // 显示边缘图像
        cv::imshow("Edges", edges); 

        int key = waitKey(30);
        if (key == 27 || key == 'q' || key == 'Q')
            break;
    }
#endif
    // 关闭所有窗口
    cv::destroyAllWindows(); 
    return 0;
}
